/*+***********************************************************************************
 Filename: 03_tinycore_step04\src\gpio.v
 Description: a simple gpio module.

 Modification:
   2022.11.07 Creation   H.Zheng

Copyright (C) 2022  Zheng Hui (hzheng@gzhu.edu.cn)

License: MulanPSL-2.0

***********************************************************************************-*/

module gpio (
    input wire clk,
    input wire reset_n,
    input wire button,
    output wire [5:0] led,
    input wire ce, //chip enable
    input wire wre, //write enable
    input wire [1:0] addr, //address bus
    input wire [31:0] data_in,
    output wire [31:0] data_out

);

    reg [31:0] data_out_reg;
    reg [31:0] data_in_reg;

    //write data_out register
    always @(posedge clk) begin
        if (~reset_n) begin
            data_out_reg <= 32'b0;
        end
        else if (ce & wre & (addr==2'b00)) begin
            data_out_reg <= data_in;
        end
    end    

    //latch input
    always @(posedge clk) begin
        if (~reset_n) begin
            data_in_reg <= 32'b0;
        end
        else begin
            data_in_reg <= {31'b0, button};
        end
    end    

    //whie core read

    assign data_out = ~((ce == 1'b1) & (wre == 1'b0)) ? 32'bz :   //if not read, return high Z
                        (addr==2'b00) ? data_out_reg :
                        (addr==2'b01) ? data_in_reg : 32'bz;


    //led
    assign led = ~data_out_reg[5:0];

endmodule
